package com.niiwoo.civet.trade.service.dubbo.loan;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.trade.constant.LoanFlowMqConstant;
import com.niiwoo.civet.trade.dao.entity.ProjectFlowExecuteRuntime;
import com.niiwoo.civet.trade.dao.mapper.ProjectFlowExecuteRuntimeMapperExt;
import com.niiwoo.civet.trade.dto.request.loan.ProjectFlowExecuteRuntimeDTO;
import com.niiwoo.civet.trade.enums.LoanNodeTypeEnum;
import com.niiwoo.civet.trade.service.loan.LoanTimedTaskDubboService;
import com.niiwoo.civet.trade.service.loan.antifraud.LoanAntiFraudDubboService;
import com.niiwoo.civet.trade.service.loan.credit.CreditAmountDubboService;
import com.niiwoo.civet.trade.service.local.flowexecute.ProjectFlowExecuteService;
import com.niiwoo.civet.trade.service.local.loan.creditaduit.CreditAuditCompositeService;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Slf4j
@Service(version = "1.0.0")
public class LoanTimedTaskDubboServiceImpl implements LoanTimedTaskDubboService {
	
	private static final int tianchengCallbackTimeoutRepairPriod = 10; //10分钟
	
	@Autowired
    private ProjectFlowExecuteRuntimeMapperExt projectFlowExecuteRuntimeMapperExt;
	@Autowired
	private CreditAuditCompositeService creditAuditCompositeService;

	@Reference(version = "1.0.0")
    private CreditAmountDubboService creditAmountDubboService;
	@Reference(version = "1.0.0")
	private LoanAntiFraudDubboService loanAntiFraudDubboService;

	@Autowired
	private ProjectFlowExecuteService projectFlowExecuteService;

	/**
	 * 借款流程异常重试
	 */
	@Override
	public void loanFlowExceptionRetry() {
		//TODO: 
		//1. 查询t_tc_project_flow_execute_runtime表中所有node_status=1且t_tc_project_flow_execute表中status=0的记录
		//2.
		// shardingjdbc 强制走主库
		if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
		List<ProjectFlowExecuteRuntime> list = projectFlowExecuteRuntimeMapperExt.findLoanFlowExceptionRetryRecord();
		
		if (list == null || list.isEmpty()) return;
		
		for (ProjectFlowExecuteRuntime flow : list) {
			LoanNodeTypeEnum nodeType = LoanNodeTypeEnum.enumof(flow.getNodeId());
			if (nodeType == null) {
				log.info("流程节点节点异常={}.", flow.getFlowExecuteId());
				continue;
			}
			ProjectFlowExecuteRuntimeDTO projectFlowExecuteRuntimeDTO = buildProjectFlowExecuteRuntimeDTO(flow);
			switch (nodeType) {
				case LOAN_ANTI_FRAUD: //借款反欺诈
					loanAntiFraudDubboService.retryTime(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_LIMIT_SCORE: //额度评分卡
					creditAmountDubboService.retryCallTcAmountScoreCard(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_TE_LIMIT_SCORE: //提额额度评分卡
					creditAmountDubboService.teRetryCallTcAmountScoreCard(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_TE_LIMIT_SCORE_BACK: //提额额度评分卡回调
					creditAmountDubboService.teAmountScoreBareQuery(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_SYSTEM_AUDIT: //系统审核
					creditAuditCompositeService.callTianchengCreditAuditService(flow.getFlowExecuteId());
					break;
				case LOAN_DATA_BACK_FLOW: //借款相关数据回流
					projectFlowExecuteService.sendLoanFlowMq(flow.getFlowExecuteId(), LoanFlowMqConstant.Queue.LOAN_DATA_BACK_FLOW_QUEUE);
					break;
				case AUTH_STATUS_CHECK: //授权状态检测
					projectFlowExecuteService.sendLoanFlowMq(flow.getFlowExecuteId(), LoanFlowMqConstant.Queue.AUTH_STATUS_CHECK_QUEUE);
					break;
				case RISK_INFO_HANDLE: //12项风险规则处理
					projectFlowExecuteService.sendLoanFlowMq(flow.getFlowExecuteId(), LoanFlowMqConstant.Queue.RISK_INFO_HANDLE_QUEUE);
					break;
				case LOAN_ANTI_FRAUD_BACK: //借款反欺诈回调
				case LOAN_LIMIT_SCORE_BACK: //额度评分卡回调
				case LOAN_SYSTEM_AUDIT_BACK: //系统审核回调
				case PORTRAIT_AUTH: //肖像认证
				case MANPOWER_AUDIT: //人工审核
				case PROJECT_TO_BANK: //上标(自动审核开关开启)
				default:
					log.info("流程节点={},不需要处理.",nodeType.getDesc());
			}
		}
	}
	
	private ProjectFlowExecuteRuntimeDTO buildProjectFlowExecuteRuntimeDTO(ProjectFlowExecuteRuntime flow) {
		ProjectFlowExecuteRuntimeDTO dto = new ProjectFlowExecuteRuntimeDTO();
		
		BeanUtils.copyProperties(flow, dto);
		
		return dto;
	}

	/**
	 * 通过天秤补漏接口主动查询天秤结果
	 */
	@Override
	public void activeQueryTianchengResult() {
		//TODO: 
		//1. 查询t_tc_project_flow_execute_runtime表中所有node_status=0,update_time为10分钟前且t_tc_project_flow_execute表中status=0的记录

		// shardingjdbc 强制走主库
		if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
		DateTime dt = new DateTime();
		dt = dt.minusMinutes(tianchengCallbackTimeoutRepairPriod);
		List<ProjectFlowExecuteRuntime> list = projectFlowExecuteRuntimeMapperExt.findTianchengCallbackTimeOutRecord(dt.toDate());
		
		if (list == null || list.isEmpty()) return;
		
		for (ProjectFlowExecuteRuntime flow : list) {
			LoanNodeTypeEnum nodeType = LoanNodeTypeEnum.enumof(flow.getNodeId());
			if (nodeType == null) {
				log.info("流程节点节点异常={}.", flow.getFlowExecuteId());
				continue;
			}

			ProjectFlowExecuteRuntimeDTO projectFlowExecuteRuntimeDTO = buildProjectFlowExecuteRuntimeDTO(flow);
			switch (nodeType) {
				case LOAN_ANTI_FRAUD_BACK: //借款反欺诈回调
					loanAntiFraudDubboService.repairServiceAntiFraud(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_LIMIT_SCORE_BACK: //额度评分卡回调
					creditAmountDubboService.amountScoreBareQuery(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_TE_LIMIT_SCORE_BACK: //借款提额额度评分卡回调
					creditAmountDubboService.teAmountScoreBareQuery(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_SYSTEM_AUDIT_BACK: //系统审核回调
					creditAuditCompositeService.callTianchengRepairService(flow.getFlowExecuteId());
					break;
				case LOAN_DATA_BACK_FLOW: //借款相关数据回流
					projectFlowExecuteService.sendLoanFlowMq(flow.getFlowExecuteId(), LoanFlowMqConstant.Queue.LOAN_DATA_BACK_FLOW_QUEUE);
					break;
				case AUTH_STATUS_CHECK: //授权状态检测
					projectFlowExecuteService.sendLoanFlowMq(flow.getFlowExecuteId(), LoanFlowMqConstant.Queue.AUTH_STATUS_CHECK_QUEUE);
					break;
				case RISK_INFO_HANDLE: //12项风险规则处理
					projectFlowExecuteService.sendLoanFlowMq(flow.getFlowExecuteId(), LoanFlowMqConstant.Queue.RISK_INFO_HANDLE_QUEUE);
					break;
					
				//调用天秤超时重试
				case LOAN_ANTI_FRAUD: //借款反欺诈
					loanAntiFraudDubboService.retryTime(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_LIMIT_SCORE: //额度评分卡
					creditAmountDubboService.retryCallTcAmountScoreCard(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_TE_LIMIT_SCORE: //提额额度评分卡
					creditAmountDubboService.teRetryCallTcAmountScoreCard(projectFlowExecuteRuntimeDTO);
					break;
				case LOAN_SYSTEM_AUDIT: //系统审核
					creditAuditCompositeService.callTianchengCreditAuditService(flow.getFlowExecuteId());
					break;
				case PORTRAIT_AUTH: //肖像认证
				case MANPOWER_AUDIT: //人工审核
				case PROJECT_TO_BANK: //上标(自动审核开关开启)
				default:
					log.info("流程节点={},不需要处理.",nodeType.getDesc());
			}
		}
	}

}
